package services

import (
	"fmt"
	"time"

	"go.uber.org/zap"

	"dcarpai-guider/internal/models"
	"dcarpai-guider/internal/utils"
)

// ToolService 工具服务
type ToolService struct {
	fileManager  *utils.FileManager
	consulClient *utils.ConsulClient
	logger       *zap.Logger
	dataPath     string
}

// NewToolService 创建新的工具服务
func NewToolService(fileManager *utils.FileManager, consulClient *utils.ConsulClient, logger *zap.Logger) *ToolService {
	return &ToolService{
		fileManager:  fileManager,
		consulClient: consulClient,
		logger:       logger,
		dataPath:     "data/tools.json",
	}
}

// GetAllTools 获取所有工具
func (ts *ToolService) GetAllTools() ([]models.Tool, error) {
	var tools []models.Tool
	if err := ts.fileManager.ReadJSON(ts.dataPath, &tools); err != nil {
		ts.logger.Error("读取工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("读取工具数据失败: %w", err)
	}

	return tools, nil
}

// GetTool 根据ID获取工具
func (ts *ToolService) GetTool(id int) (*models.Tool, error) {
	var tools []models.Tool
	if err := ts.fileManager.ReadJSON(ts.dataPath, &tools); err != nil {
		ts.logger.Error("读取工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("读取工具数据失败: %w", err)
	}

	for _, tool := range tools {
		if tool.ID == id {
			return &tool, nil
		}
	}

	return nil, fmt.Errorf("工具不存在")
}

// CreateTool 创建新工具
func (ts *ToolService) CreateTool(req *models.ToolRequest) (*models.Tool, error) {
	var tools []models.Tool
	if err := ts.fileManager.ReadJSON(ts.dataPath, &tools); err != nil {
		ts.logger.Error("读取工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("读取工具数据失败: %w", err)
	}

	// 生成新的工具ID
	maxID := 0
	for _, tool := range tools {
		if tool.ID > maxID {
			maxID = tool.ID
		}
	}

	// 设置默认状态
	status := req.Status
	if status == "" {
		status = "active"
	}

	// 创建新工具
	newTool := models.Tool{
		ID:          maxID + 1,
		Name:        req.Name,
		Description: req.Description,
		EmbedURL:    req.EmbedURL,
		ConsulID:    req.ConsulID,
		Status:      status,
		Created:     time.Now().Format(time.RFC3339),
	}

	// 如果提供了ConsulID，尝试检查服务状态
	if ts.consulClient != nil && newTool.ConsulID != "" {
		if _, err := ts.consulClient.GetService(newTool.ConsulID); err != nil {
			ts.logger.Warn("Consul服务不存在或无法访问",
				zap.String("consul_id", newTool.ConsulID),
				zap.Error(err),
			)
			// 不阻止创建，但记录警告
		} else {
			ts.logger.Info("已关联Consul服务", zap.String("consul_id", newTool.ConsulID))
		}
	}

	// 添加到工具列表
	tools = append(tools, newTool)

	// 保存到文件
	if err := ts.fileManager.WriteJSON(ts.dataPath, tools); err != nil {
		ts.logger.Error("保存工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("保存工具数据失败: %w", err)
	}

	ts.logger.Info("创建工具成功",
		zap.String("name", newTool.Name),
		zap.Int("id", newTool.ID),
	)

	return &newTool, nil
}

// UpdateTool 更新工具
func (ts *ToolService) UpdateTool(id int, req *models.ToolRequest) (*models.Tool, error) {
	var tools []models.Tool
	if err := ts.fileManager.ReadJSON(ts.dataPath, &tools); err != nil {
		ts.logger.Error("读取工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("读取工具数据失败: %w", err)
	}

	// 查找并更新工具
	var updatedTool *models.Tool
	for i := range tools {
		if tools[i].ID == id {
			tools[i].Name = req.Name
			tools[i].Description = req.Description
			tools[i].EmbedURL = req.EmbedURL
			tools[i].ConsulID = req.ConsulID
			if req.Status != "" {
				tools[i].Status = req.Status
			}
			tools[i].Updated = time.Now().Format(time.RFC3339)
			updatedTool = &tools[i]
			break
		}
	}

	if updatedTool == nil {
		return nil, fmt.Errorf("工具不存在")
	}

	// 检查Consul服务状态
	if ts.consulClient != nil && updatedTool.ConsulID != "" {
		if _, err := ts.consulClient.GetService(updatedTool.ConsulID); err != nil {
			ts.logger.Warn("Consul服务不存在或无法访问",
				zap.String("consul_id", updatedTool.ConsulID),
				zap.Error(err),
			)
		}
	}

	// 保存到文件
	if err := ts.fileManager.WriteJSON(ts.dataPath, tools); err != nil {
		ts.logger.Error("保存工具数据失败", zap.Error(err))
		return nil, fmt.Errorf("保存工具数据失败: %w", err)
	}

	ts.logger.Info("更新工具成功",
		zap.String("name", updatedTool.Name),
		zap.Int("id", id),
	)

	return updatedTool, nil
}

// DeleteTool 删除工具
func (ts *ToolService) DeleteTool(id int) error {
	var tools []models.Tool
	if err := ts.fileManager.ReadJSON(ts.dataPath, &tools); err != nil {
		ts.logger.Error("读取工具数据失败", zap.Error(err))
		return fmt.Errorf("读取工具数据失败: %w", err)
	}

	// 查找并删除工具
	found := false
	var newTools []models.Tool
	for _, tool := range tools {
		if tool.ID != id {
			newTools = append(newTools, tool)
		} else {
			found = true
			ts.logger.Info("准备删除工具",
				zap.String("name", tool.Name),
				zap.Int("id", id),
			)
		}
	}

	if !found {
		return fmt.Errorf("工具不存在")
	}

	// 保存到文件
	if err := ts.fileManager.WriteJSON(ts.dataPath, newTools); err != nil {
		ts.logger.Error("保存工具数据失败", zap.Error(err))
		return fmt.Errorf("保存工具数据失败: %w", err)
	}

	ts.logger.Info("删除工具成功", zap.Int("id", id))
	return nil
}

// GetToolStatus 获取工具状态（包括Consul健康检查）
func (ts *ToolService) GetToolStatus(id int) (map[string]interface{}, error) {
	tool, err := ts.GetTool(id)
	if err != nil {
		return nil, err
	}

	status := map[string]interface{}{
		"tool_id":    tool.ID,
		"tool_name":  tool.Name,
		"status":     tool.Status,
		"embed_url":  tool.EmbedURL,
		"consul_id":  tool.ConsulID,
		"last_check": time.Now().Format(time.RFC3339),
	}

	// 如果有Consul ID，检查服务健康状态
	if ts.consulClient != nil && tool.ConsulID != "" {
		healthy, err := ts.consulClient.HealthCheck(tool.ConsulID)
		if err != nil {
			status["consul_status"] = "unknown"
			status["consul_error"] = err.Error()
		} else {
			if healthy {
				status["consul_status"] = "healthy"
			} else {
				status["consul_status"] = "unhealthy"
			}
		}

		// 获取服务详细信息
		service, err := ts.consulClient.GetService(tool.ConsulID)
		if err == nil {
			status["service_address"] = service.Address
			status["service_port"] = service.Port
			status["service_tags"] = service.Tags
		}
	} else {
		status["consul_status"] = "not_configured"
	}

	return status, nil
}

// GetActiveTools 获取活跃的工具
func (ts *ToolService) GetActiveTools() ([]models.Tool, error) {
	tools, err := ts.GetAllTools()
	if err != nil {
		return nil, err
	}

	var activeTools []models.Tool
	for _, tool := range tools {
		if tool.Status == "active" {
			activeTools = append(activeTools, tool)
		}
	}

	return activeTools, nil
}
